package com.libgdxbar.pvzlikegame.entities;

import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.IntMap;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * <h3>EntityGroup类负责管理游戏中的所有实体对象的增删以及系统管理</h3>
 */
public final class EntityGroup implements Disposable {

	// 使用Singleton模式确保只有一个EntityGroup实例
	@SuppressWarnings("GDXJavaStaticResource")
	private static EntityGroup instance;
	// 存储所有实体、可渲染作业和可更新对象的数组
	public IntMap<BaseEntity> _all = new IntMap<>();
	// 防止系统重复添加
	private Map<Class<?>, EntitySystem> systems = new LinkedHashMap<>();
	private Map<Class<?>, EntityListener> listeners = new LinkedHashMap<>();

	/**
	 * 防止外部通过构造函数创建EntityGroup实例，确保单例模式的实现。
	 */
	private EntityGroup() throws RuntimeException {
		if (instance != null) {
			throw new RuntimeException("单例实体，不允许重复创建");
		}
	}

	/**
	 * 获取EntityGroup的单例实例
	 *
	 * @return EntityGroup的实例
	 */
	public static synchronized EntityGroup getInstance() {
		if (instance == null) {
			instance = new EntityGroup();
		}
		return instance;
	}

	/**
	 * 向EntityGroup中添加一个实体对象
	 *
	 * @param baseEntity 要添加的实体对象
	 */
	public void addEntity(BaseEntity baseEntity) {
		// 防止重复添加实体
		if (_all.containsKey(baseEntity.id)) {
			return;
		}
		// 通知实体添加
		for (EntityListener entityListener : listeners.values()) {
			entityListener.onEntityAdded(baseEntity);
		}
		_all.put(baseEntity.id, baseEntity);
	}

	/**
	 * 从EntityGroup中移除一个实体对象
	 *
	 * @param baseEntity 要移除的实体对象
	 */
	public void removeEntity(BaseEntity baseEntity) {
		// 实体不存在
		if (!_all.containsKey(baseEntity.id)) {
			return;
		}
		// 通知实体移除
		for (EntityListener entityListener : listeners.values()) {
			entityListener.onEntityRemoved(baseEntity);
		}
		_all.remove(baseEntity.id);
	}

	public <T extends EntitySystem> T getSystem(Class<T> clazz){
		return (T) systems.get(clazz);
	}

	public void addSystem(EntitySystem entitySystem) {
		// 防止重复添加系统
		if (!systems.containsKey(entitySystem.getClass())) {
			systems.put(entitySystem.getClass(), entitySystem);
			this.addEntityListener(entitySystem);
		}
	}

	public void removeSystem(Class<? extends EntitySystem> clazz) {
		EntitySystem remove = systems.remove(clazz);
		this.removeEntityListener(remove);
	}

	public void addEntityListener(EntityListener entityListener) {
		listeners.put(entityListener.getClass(), entityListener);
	}

	public void removeEntityListener(EntityListener entityListener) {
		listeners.remove(entityListener.getClass());
	}

	/**
	 * 更新所有实体对象的状态
	 *
	 * @param delta 自上次更新以来的时间间隔
	 */
	public void update(float delta) {
		for (EntitySystem system : systems.values()) {
			system.run(delta);
		}
	}

	/**
	 * 释放所有实体对象的资源
	 */
	@Override
	public void dispose() {
		for (EntityListener listener : listeners.values()) {
			if (listener instanceof Disposable) {
				Disposable disposable = (Disposable) listener;
				disposable.dispose();
			}
		}
		for (BaseEntity baseEntity : _all.values()) {
			if (baseEntity instanceof Disposable) {
				Disposable disposable = (Disposable) baseEntity;
				disposable.dispose();
			}
		}
		_all.clear();
		listeners.clear();
		systems.clear();
	}

}
